package com.bjpowernode.mvc.service.Impl;

import com.bjpowernode.common.CommonUtil;
import com.bjpowernode.common.client.RedisClient;
import com.bjpowernode.common.consts.AppConst;
import com.bjpowernode.common.consts.Keys;
import com.bjpowernode.common.enums.Code;
import com.bjpowernode.db.domain.*;
import com.bjpowernode.db.result.BidProductResult;
import com.bjpowernode.db.result.BidUserResultMapping;
import com.bjpowernode.mvc.model.dto.bid.BidProductDTO;
import com.bjpowernode.mvc.model.dto.bid.BidRankDTO;
import com.bjpowernode.mvc.service.BaseService;
import com.bjpowernode.mvc.service.inter.BidService;
import io.lettuce.core.BitFieldArgs;
import jakarta.annotation.Resource;
import lombok.val;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;


@Service
public class BidServiceImpl extends BaseService implements BidService {


    @Resource
    private RedisClient redisClient;

    @Override
    public List<BidRankDTO> queryBidRankFromRedis() {

        Set<ZSetOperations.TypedTuple<String>>  tuples = redisClient.reverseRangeWithScore(Keys.BID_RANK, 0, 2);

        List<BidRankDTO> rankDTOList=new ArrayList<>();
        tuples.forEach(rank->{
            rankDTOList.add(new BidRankDTO(rank.getValue(),new BigDecimal(rank.getScore())));
        });
        return rankDTOList;
    }

    @Override
    public List<BidUserResultMapping> queryRecentlyBidsByProductId(Integer productId, Integer pageNo, Integer pageSize) {

        int offset=(pageNo-1)*pageSize;
       return bidInfoMapper.selectAllByProduct(productId,offset,pageSize);

    }


    //投资购买的理财产品
    @Override
    public String buyProduct(BidProductDTO bidProductDTO) {

        //查询账户余额.
       FinanceAccount account= accountMapper.selectByUidForUpdate(bidProductDTO.getProductId());
       if (account == null){
           return Code.ACCOUNT_NOT_EXSITS.name();
       }


       //账户的余额
       if (CommonUtil.lt(account.getAvailableMoney(),bidProductDTO.getBidMoney())){
           return Code.ACCOUNT_MONEY_NOT.name();
       }

       //查询理财产品剩余可投资金额..
      ProductInfo productInfo= productInfoMapper.selectByIdForUpdate(bidProductDTO.getProductId());

       if (productInfo == null){
           return Code.PEODUCT_NOT.name();
       }



       //判断余额.
        if (CommonUtil.lt(productInfo.getLeftProductMoney(),bidProductDTO.getBidMoney())){
            return Code.PEODUCT_LERT_NOT.name();
        }


        //最小和最大
        if (CommonUtil.lt(bidProductDTO.getBidMoney(),productInfo.getBidMinLimit())){
            return Code.BID_MONEY_RANGE_ERR.name();
        }
        if (CommonUtil.gt(bidProductDTO.getBidMoney(),productInfo.getBidMaxLimit())){
            return Code.BID_MONEY_RANGE_ERR.name();
        }



        //扣除账户余额.
       int rows= accountMapper.reduceAccountMoneyByBid(bidProductDTO.getUserId(),bidProductDTO.getBidMoney());

        if (rows<1){
            throw new RuntimeException("投资,购买理财产品失败");
        }


        //扣除产品剩余可投资金额
        rows=productInfoMapper.reduceLeftAvalableMoney(bidProductDTO.getProductId(),bidProductDTO.getBidMoney());

        if (rows<1){
            throw new RuntimeException("投资,扣除产品剩余可投资金额失败");
        }



        //更新账户的流水
        AccountDetail accountDetail=new AccountDetail();
        accountDetail.setUid(bidProductDTO.getUserId());
        accountDetail.setAction(AppConst.SUB);
        accountDetail.setActionTime(new Date());
        accountDetail.setMoney(bidProductDTO.getBidMoney());
        accountDetail.setMemo(bidProductDTO.getUserId()+"投资购买"+bidProductDTO.getProductId()+",金额"+bidProductDTO.getBidMoney());

        accountDetailMapper.insert(accountDetail);



        //生成投资记录.
        BidInfo bidInfo=new BidInfo();
        bidInfo.setProdId(bidProductDTO.getProductId());
        bidInfo.setUid(bidProductDTO.getUserId());
        bidInfo.setBidMoney(bidProductDTO.getBidMoney());
        bidInfo.setBidTime(new Date());
        bidInfo.setBidStatus(AppConst.BID_SUCC);

        bidInfoMapper.insert(bidInfo);


        //是否满标.
        ProductInfo query=productInfoMapper.selectById(bidProductDTO.getProductId());
        if (query.getLeftProductMoney().compareTo(new BigDecimal("0"))==0){
            //更新产品满标时间和状态
            ProductInfo update =new ProductInfo();
            update.setId(query.getId());
            update.setProductFullTime(new Date());
            update.setProductStatus(AppConst.STATUS_MAN_BIAO);

            rows=productInfoMapper.updateById(update);
            if (rows<1){
                throw new RuntimeException("投资,扣除剩余可投资资金失败.");
            }

        }



        return Code.SUCC.name();
    }


    //更新投资排行榜
    @Override
    public void modifyBidRank(Integer userId, BigDecimal bidMoney) {
        User user=userMapper.selectById(userId);
        redisClient.incrementScore(Keys.BID_RANK,user.getPhone(),bidMoney.doubleValue());
    }

    //查询用户的投资记录
    @Override
    public List<BidProductResult> queryRecentlyBidsByUserId(Integer userId, Integer pageNo, Integer pageSize) {

        int Offset=(pageNo-1)*pageSize;
      return bidInfoMapper.selectBidListByUserId(userId, Offset,pageSize);

    }
}
